package com.starview.platform.data.type;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class ConstraintFinder extends AbstractTypeVisitor
{
  private List<ITypeConstraint> constraints = new ArrayList<ITypeConstraint>();
  private Set<TypeVar> vars = new HashSet<>();

  public static List<ITypeConstraint> findConstraints(IType type)
  {
    ConstraintFinder finder = new ConstraintFinder();
    type.accept(finder);

    return finder.getConstraints();
  }

  public static List<ITypeConstraint> findConstraints(Collection<IType> types)
  {
    ConstraintFinder finder = new ConstraintFinder();
    for (IType type : types)
      type.accept(finder);

    return finder.getConstraints();
  }

  private List<ITypeConstraint> getConstraints()
  {
    return constraints;
  }

  @Override
  public void visitTypeVar(TypeVar v)
  {
    IType t = v.deRef();
    if (t instanceof TypeVar) {
      v = (TypeVar) t;
      if (!vars.contains(v) && !isExcluded(v.getVarName())) {
        vars.add(v);
        for (ITypeConstraint con : v) {
          if (!(constraints.contains(con))) {
            constraints.add(con);
            con.accept(this);
          }
        }
      }
    } else
      t.accept(this);
  }
}